import 'const_params.dart' as ConstParams;

typedef ValueChanged = void Function<T>(T item);
void main() async {
  // void someFunction(Object item, {required int a, int b: 0, Object? c}) {
  //   if (c != null) {
  //     print(c);
  //   }
  // }

  int a = 127;
  int b = 127;
  print(a == b);
  print(a.hashCode);
  print(b.hashCode);

  int c = 128;
  int d = 128;
  print(c == d);

  String str1 = 'a';
  String str2 = 'a';
  print(str1 == str2);

  String str3 = '岛上码农';
  String str4 = '岛上码农';
  print('汉字：${str3 == str4}');

  print('max: ${ConstParams.maxLength}');

  // void someFunction1({a: int, b: int}) {}

  // someFunction1(a: 'null', b: null);
  someFunction(0, 'b');
  someFunction1(1, d: 12);

  var list = ['1', '2', 1, 2];

  var copy2 = list.whereType<int>();
  var copy1 = list.where((e) => e is int);

  print(copy1.runtimeType);
  print(copy2.toList().runtimeType);

  var printMsg = (msg) => print(msg);
  printMsg('hello');

  void sayHello({name: String}) {
    print(name);
    print(name.runtimeType);
    print('Hello, $name');
  }

  sayHello();
  sayHello(name: 'Jack');

  void callbackFunc({callback: ValueChanged}) {
    callback('Jack');
  }

  callbackFunc(callback: (name) {
    print('Hello, $name');
  });

  var person = Person.withAssert('Allen', 19);
  print(person);

  var student = Student('Allen', 15, 'XX School');
  student.speakEnglish();
  print(student);

  try {
    var person1 = Person.fromJson({'name': 'Jack', 'age': '18'});
    print(person1);
  } on TypeError catch (e, s) {
    print('Error: $e, Stack: $s');
  } on ArgumentError catch (e, s) {}

  var person1 = Person.fromJson({'name': 'Jack', 'age': -1});
  await Student.printP(person1);
}

class Test {
  double amount(double value) => value * 10.0;
}

class Person {
  late String name;
  late int age;

  Person(this.name, this.age);

  Person.fromJson(Map<String, dynamic> json) {
    name = json['name'];
    age = json['age'];
  }

  Person.withAssert(this.name, this.age)
      : assert(age >= 0),
        assert(name.length > 0);

  String toString() {
    fakeOverload();
    return 'name: $name, age: $age';
  }

  void fakeOverload([dynamic type]) {
    if (type is String) {
      // 处理 字符串
    } else if (type is num) {
      // 处理数值
    } else {
      //...
    }
  }

  factory Person.withType(String type) {
    if (type == 'student') {
      return Student('Allen', 15, 'XX School');
    } else {
      return Person('Allen', 15);
    }
  }
}

class Student extends Person with SpeakEnglishMixin {
  String school;
  Student(name, age, this.school) : super(name, age);

  String toString() {
    return 'name: $name, age: $age, school: $school';
  }

  static Future<void> printP(Person person) async {
    if (person.age < 0) throw ArgumentError('Invalid age of Person');

    print(person.toString());
    someFunction1(1, c: Person.withType('type'));
  }
}

mixin SpeakEnglishMixin on Person {
  void speakEnglish() {
    print('I can speak English fluently');
  }
}

void someFunction(int a, [String c = 'c', String? b]) {
  print('a: $a, b:$b, c:$c');
  // ...
}

void someFunction1(int a, {Person? c, int d = 0, Student? s}) {
  // ...
}
